package com.wind.test;

import com.wind.entity.Cache;
import com.wind.entity.Customer;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import javax.persistence.*;
import java.util.List;

public class JpaTest05_JPQL_HelloWorld {

  private EntityManagerFactory entityManagerFactory;
  private EntityManager entityManager;
  private EntityTransaction entityTransaction;

  @Before
  public void init() {
    entityManagerFactory = Persistence.createEntityManagerFactory("JpaDemo");
    entityManager = entityManagerFactory.createEntityManager();
    entityTransaction = entityManager.getTransaction();
    entityTransaction.begin();
  }

  @After
  public void destory() {
    entityTransaction.commit();
    entityManager.close();
    entityManagerFactory.close();
  }

  /*
     entityManager.createQuery(jpql)
     query.setParameter(new Integer(1), 1);
     query.getResultList()
   */
  @Test
  public void testJpqlHelloWorld() {
//    String jpql = "FROM Customer c WHERE c.id = ?";
    String jpql = "FROM Cache where id = ?";
    Query query = entityManager.createQuery(jpql);
//    query.setParameter(new Integer(1), 2);
//    这条语句会报如下异常：
//      WARN: [DEPRECATION]
//      Encountered positional parameter near line 1, column 46.
//      Positional parameter are considered deprecated;
//      use named parameters or JPA-style positional parameters instead.

    //占位符的索引是从 1 开始
    query.setParameter(new Integer(1), 1); // 直接写 1 报这错误：Cannot resolve query parameter '1'
    List<Customer> result = query.getResultList();
    System.out.println(result);
  }


  /*
    默认情况下, 若只查询部分属性, 则将返回 Object[] 类型的结果. 或者 Object[] 类型的 List.
    也可以在实体类中创建对应的构造器, 然后再 JPQL 语句中利用对应的构造器返回实体类的对象.
   */
  @Test
  public void testJpqlBean() {
    //                  "虽然写的 SQL 但是 表、属性 和数据库的没一点关系~！"
    String jpqlObject = "SELECT name, age FROM Cache WHERE id = ?";
    String jpqlCache = "SELECT new Cache(name, age) FROM Cache WHERE id = ?";

    List resultObject = entityManager.createQuery(jpqlObject)
      .setParameter(new Integer(1), 1)
      .getResultList();
    System.out.println(resultObject);

    List resultCache = entityManager.createQuery(jpqlCache)
      .setParameter(new Integer(1), 1)
      .getResultList();
    System.out.println(resultCache);
  }

  /*
    测试 NamedQuery：
      entityManager.createNamedQuery
      query.getSingleResult()
   */
  @Test
  public void testNameQuery() {
    Query query = entityManager.createNamedQuery("CacheQuery").setParameter(new Integer(1), 1);
    Cache cache = (Cache) query.getSingleResult();
    System.out.println(cache);
  }

  /*
    测试 NativeQuery
   */
  @Test
  public void testNativeQuery() {
    // SELECT 一个列会获取该值 ，两个列的话返回的是个对象？？？What~！@
    String sql = "SELECT `name` FROM `jap_cache` WHERE `id` = ?";
    Query nativeQuery = entityManager.createNativeQuery(sql).setParameter(new Integer(1), 1);
//    Cache result = (Cache) nativeQuery.getSingleResult();  // java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to com.wind.entity.Cache（强转会报错？Fuck~！）
    Object result = nativeQuery.getSingleResult();
    System.out.println(result);
  }

}
